//
//  Array.swift
//  vgbox
//
//  Created by 宋海胜 on 2019/6/25.
//  Copyright © 2019 Swift Xcode. All rights reserved.
//

import Foundation
import RxCocoa
import RxSwift

extension Array {
    
    /// 数组移除元素
    mutating func removeValue(_ value: AnyObject) {
        
        let arr = self.filter { (e) -> Bool in
            let objc = e as AnyObject
            return !objc.isEqual(value)
        }
        
        self = arr
    }
    
    func objectAtIndex(index: Int) -> Element? {
        if self.count > index && index >= 0 {
            return self[index]
        }
        else {
            return nil
        }
    }

    /// 数组转jsonString
    func getJSONString(prettyPrint: Bool = false) -> String {
        guard count > 0 else { return "" }
        guard JSONSerialization.isValidJSONObject(self) else { return "" }
        let data = try? JSONSerialization.data(withJSONObject: self, options: prettyPrint ? .prettyPrinted : [])
        if let data = data {
            return String(data: data, encoding: .utf8) ?? ""
        }
        return ""
    }
    
    /// array转array样式的字符串
    func getArrayString() -> String {
        if self.count == 0 {
            return "[]"
        }
        return (self as! [String]).joined(separator: ",")
    }
    
    /// array转urlencode
    func getEncodeString() -> String {
        for item in self {
            if !(item is String) {
                return ""
            }
        }
        return (self as! [String]).joined(separator: ",").getEncodeString
    }
    
    /// 数组顺序打乱
    static func disorderArray(orginalArr: [Element]) -> [Element] {
        var tempArr: [Element] = []
        var orginalArrCopy: [Element] = []
        orginalArrCopy = orginalArr
        while orginalArrCopy.count > 0 {
            let i: Int = Int(arc4random_uniform(UInt32(orginalArrCopy.count)))
            tempArr.append(orginalArrCopy[i])
            orginalArrCopy.remove(at: i)
        }
        return tempArr
    }
    
    /// 从数组中返回一个随机元素
    public var sample: Element? {
        //如果数组为空，则返回nil
        guard count > 0 else { return nil }
        let randomIndex = Int(arc4random_uniform(UInt32(count)))
        return self[randomIndex]
    }
    
    /// 从数组中从返回指定个数的元素
    ///
    /// - Parameters:
    ///   - size: 希望返回的元素个数
    ///   - noRepeat: 返回的元素是否不可以重复（默认为false，可以重复）
    public func sample(size: Int, noRepeat: Bool = false) -> [Element]? {
        //如果数组为空，则返回nil
        guard !isEmpty else { return nil }
        
        var sampleElements: [Element] = []
        
        //返回的元素可以重复的情况
        if !noRepeat {
            for _ in 0..<size {
                sampleElements.append(sample!)
            }
        }
            //返回的元素不可以重复的情况
        else{
            //先复制一个新数组
            var copy = self.map { $0 }
            for _ in 0..<size {
                //当元素不能重复时，最多只能返回原数组个数的元素
                if copy.isEmpty { break }
                let randomIndex = Int(arc4random_uniform(UInt32(copy.count)))
                let element = copy[randomIndex]
                sampleElements.append(element)
                //每取出一个元素则将其从复制出来的新数组中移除
                copy.remove(at: randomIndex)
            }
        }
        return sampleElements
    }

}


extension Array where Element:Hashable{
    
    /// 数组去重
    var unique : [Element] {
        var keys:[Element:()] = [:]
        return filter{keys.updateValue((), forKey:$0) == nil}
    }
    
    /// 该函数的参数filterCall是一个带返回值的闭包，传入模型T，返回一个E类型
    func handleFilter<E: Equatable>(_ filterCall: (Element) -> E) -> [Element] {
        var temp = [Element]()
        for model in self {
            //调用filterCall，获得需要用来判断的属性E
            let identifer = filterCall(model)
            //此处利用map函数 来将model类型数组转换成E类型的数组，以此来判断identifer 是否已经存在，如不存在则将model添加进temp
            if !temp.map( { filterCall($0) } ).contains(identifer) {
                temp.append(model)
            }
        }
        return temp
    }

}
